#include "ObjectManager.h"
#include "../Tokens/IBaseToken.h"
#include <assert.h>

// Instantiate the static data member
CObjectManager* CObjectManager::s_Instance = nullptr;

CObjectManager::CObjectManager(void)
{
}

CObjectManager::~CObjectManager(void)
{
}

CObjectManager* CObjectManager::GetInstance(void)
{
	// Check if there is no instance in existence
	if( s_Instance == nullptr )
		s_Instance = new CObjectManager; // If there isn't create one

	// Return the instance
	return s_Instance;
}


void CObjectManager::DeleteInstance(void)
{
	// Delete the instance
	delete s_Instance;

	// Set it back to null
	s_Instance = nullptr;
}

void CObjectManager::AddObject( IBaseToken* pToken )
{
	// Error-checking
	assert( pToken != nullptr && "CObjectManager::AddObject - parameter is null, FIX IT!" );

	// push the parameter into the list
	m_Objects.push_back( pToken );

	// Add a reference to the added object
	pToken->AddRef();

}

void CObjectManager::RemoveObject( IBaseToken* pToken )
{
	// Error-checking
	assert( pToken != nullptr && "CObjectManager::RemoveObject - parameter is null, FIX IT!" );

	// Search for the paramter in the list
	for( std::list< IBaseToken* >::iterator iter = m_Objects.begin(); iter != m_Objects.end(); ++iter )
	{
		if( (*iter) == pToken )
		{
			// Release the reference to the object
			pToken->Release();

			// Remove the object from our list
			m_Objects.erase( iter );
			break;
		}
	}

}

void CObjectManager::RemoveAllObjects( void )
{
	// Release each object's reference in the list
	for( std::list< IBaseToken* >::iterator iter = m_Objects.begin(); iter != m_Objects.end(); ++iter )
	{
		(*iter)->Release();
	}

	// Clear the list
	m_Objects.clear();
}

void CObjectManager::UpdateAllObjects( float fElapsedTime )
{
	// Update each of the objects in the list
	for( std::list< IBaseToken* >::iterator iter = m_Objects.begin(); iter != m_Objects.end(); ++iter )
	{
		(*iter)->Update( fElapsedTime );
	}
}

void CObjectManager::RenderAllObjects( void )
{
	// Render each of the objects in the list
	for( std::list< IBaseToken* >::iterator iter = m_Objects.begin(); iter != m_Objects.end(); ++iter )
	{
		(*iter)->Render();
	}
}

void CObjectManager::CheckCollisions( void )
{
	// Look through the list for different types to be able to collide
	for( std::list< IBaseToken* >::iterator iter = m_Objects.begin(); iter != m_Objects.end(); ++iter )
	{
		for( std::list< IBaseToken* >::iterator iter2 = m_Objects.begin(); iter2 != m_Objects.end(); ++iter2 )
		{
			// Are the types different?
			if( (*iter)->GetTokenID() != (*iter2)->GetTokenID() )
			{
				// Did they collide with each other?
				if( (*iter)->CheckCollision( (*iter2) ) == true )
				{
					// It has collided, stop checking.
					break;
				}
			}
		}
	}
}